package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.admin.AddStoreCodeBatchDto;
import com.frejoys.common.dto.common.PageDto;
import com.frejoys.common.enums.EStoreCodeNum;
import com.frejoys.common.enums.EStoreCodeStatus;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.util.*;
import com.frejoys.common.vo.admin.StoreCodeBatchListVo;
import com.frejoys.dao.entity.StoreCodeBatch;
import com.frejoys.dao.entity.StoreCodeDepository;
import com.frejoys.dao.entity.User;
import com.frejoys.dao.mapper.StoreCodeBatchMapper;
import com.frejoys.dao.mapper.StoreCodeDepositoryMapper;
import com.frejoys.dao.mapper.UserMapper;
import com.frejoys.service.StoreCodeBatchService;
import com.frejoys.service.StoreCodeDepositoryService;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class StoreCodeBatchServiceImpl extends ServiceImpl<StoreCodeBatchMapper, StoreCodeBatch> implements StoreCodeBatchService {

    private final StoreCodeDepositoryService storeCodeDepositoryService;

    private final RedisUtil redisUtil;

    private final UserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addStoreCodeBatch(AddStoreCodeBatchDto dto,Long userId) {

        if (dto.getNum() > EStoreCodeNum.maximum.getValue()){
            throw new GeneralException(HttpStatus.maximumError);
        }
        if (dto.getNum() < EStoreCodeNum.minimum.getValue()){
            throw new GeneralException(HttpStatus.minimumError);
        }

        StoreCodeBatch storeCodeBatch = new StoreCodeBatch();
        Date date = DateUtil.date();
        String ymd =DateUtil.format(date, "yyyyMMddHHmmss")+userId;

        storeCodeBatch.setUserId(userId);
        storeCodeBatch.setBatchCode(ymd);
        storeCodeBatch.setNum(dto.getNum());
        storeCodeBatch.setUpdateTime(TimeUtil.unixTime());
        storeCodeBatch.setCreateTime(TimeUtil.unixTime());
        storeCodeBatch.setStatus(EStoreCodeStatus.accomplish.getValue());
        int insert = baseMapper.insert(storeCodeBatch);

        List<StoreCodeDepository> list = new ArrayList<>();

        for (int i = 0; i < dto.getNum(); i++) {
            StoreCodeDepository s = new StoreCodeDepository();
            s.setStoreCodeBatchId(storeCodeBatch.getId());
            s.setCode(SnowflakeUtil.appNextId());
            s.setStatus(EStoreCodeStatus.await.getValue());
            list.add(s);
        }

        if (!list.isEmpty()){
            storeCodeDepositoryService.saveBatch(list);
        }

        return insert;
    }


    @Override
    public IPage<StoreCodeBatchListVo> storeCodeBatchListInfo(PageDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());

        LambdaQueryWrapper<StoreCodeBatch> wrapper = new LambdaQueryWrapper<>();
        Page<StoreCodeBatch> storeCodeBatchPage = baseMapper.selectPage(page, wrapper);
        IPage<StoreCodeBatchListVo> storeCodeBatchListVoIPage = storeCodeBatchPage.convert(storeCodeBatch -> BeanUtil.copyProperties(storeCodeBatch, StoreCodeBatchListVo.class));
        List<StoreCodeBatchListVo> list = storeCodeBatchListVoIPage.getRecords();

        if (!list.isEmpty()){
            List<Long> userIds = list.stream().map(StoreCodeBatchListVo::getUserId).toList();

            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            list.forEach(vo ->{
                if (userMap.containsKey(vo.getUserId())){
                    vo.setNickname(userMap.get(vo.getUserId()).getNickname());
                    vo.setAvatar(AppConfigUtil.getUrlPrefix(userMap.get(vo.getUserId()).getAvatar()));
                    vo.setPhone(userMap.get(vo.getUserId()).getPhone());
                }
            });

        }
        return storeCodeBatchListVoIPage;
    }
}
